package com.flqy.baselibrary;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import androidx.core.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.flqy.baselibrary.utils.NetworkUtil;
import com.flqy.baselibrary.utils.Utils;
import com.mozillaonline.providers.DownloadManager;

import java.io.UnsupportedEncodingException;
import java.net.NetworkInterface;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * The Client Seesion Object for our App, contains some necessary
 * information.
 *
 * @author Ludaiqian
 */
public class Session {

    /**
     * Application Context
     */
    private Context mContext;
    /**
     * The version of OS
     */
    private int osVersionCode;

    private String osVersion;

    /**
     * The user login status
     */
    private boolean isLogin;

    /**
     * The Application Version Code
     */
    private int versionCode;

    /**
     * The Application package name
     */
    private String packageName;

    /**
     * The Application version name
     */
    private String versionName;
    /**
     * The Application version name
     */
    private String appName;
    /**
     * 手机厂商
     */
    private String brand;

    /**
     * GSM手机的 IMEI 和 CDMA手机的 MEID.
     */
    private String imei;

    private String imsi;
    /**
     * SIM卡的序列号：
     */
    private String sim;

    /**
     * The mobile mac address
     */
    private String macAddress;


    /**
     * The user-visible version string. E.g., "1.0"
     */
    private String buildVersion;
    /**
     * The mobile model such as "Nexus One" Attention: some model type may have
     * illegal characters
     */
    private String model;
    /**
     * The singleton instance
     */

    private String androidId;
    private String phoneNumber;

    private List<NetworkChangedListener> networkChangedListeners;
    private String channel;
    private String deviceId;
    private DownloadManager mDownloadManager;

    Session(Context context) {
        mContext = context;
        osVersionCode = Build.VERSION.SDK_INT;
        buildVersion = Build.VERSION.RELEASE;
        try {
            model = URLEncoder.encode(Build.MODEL, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            model = Build.MODEL;
        }
        try {
            brand = URLEncoder.encode(Build.BRAND, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            brand = Build.BRAND;
        }
        try {
            osVersion = URLEncoder.encode(Build.VERSION.RELEASE, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            osVersion = Build.VERSION.RELEASE;
        }
        networkChangedListeners = new ArrayList<>();
        try {
            IntentFilter filter = new IntentFilter();
            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
            context.registerReceiver(mReceiver, filter);
        } catch (Exception e) {
            // TODO: handle exception
        }

        final PackageManager pm = mContext.getPackageManager();
        try {
            final PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), 0);
            versionName = pi.versionName;
            versionCode = pi.versionCode;

            final ApplicationInfo ai = pm.getApplicationInfo(mContext.getPackageName(), PackageManager.GET_META_DATA);
            appName = String.valueOf(ai.loadLabel(pm));
            packageName = mContext.getPackageName();
            if(ai.metaData!=null) {
                channel = ai.metaData.getString("UMENG_CHANNEL");
            }

        } catch (PackageManager.NameNotFoundException e) {
            // Log.d(TAG, "met some error when get application info");
        }
        androidId = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ANDROID_ID);

    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                // synchronized (Session.this) {
                boolean networkAvailable = NetworkUtil.isNetworkAvailable(mContext);
                // }
                for (NetworkChangedListener networkChangedListener : networkChangedListeners) {
                    networkChangedListener.onNetworkStateChanged(networkAvailable);
                }
            }
        }
    };

    public String getChannel() {
        return channel;
    }

    public boolean isNetworkAvailable() {
        return NetworkUtil.isNetworkAvailable(mContext);
    }

    public void addNetworkChangedListener(NetworkChangedListener networkChangedListener) {
        this.networkChangedListeners.add(networkChangedListener);
    }

    public void removeNetworkChangedListener(NetworkChangedListener networkChangedListener) {
        networkChangedListeners.remove(networkChangedListener);
    }

    public interface NetworkChangedListener {
        void onNetworkStateChanged(boolean networkAvailable);
    }


    public DownloadManager getDownloadManager() {
        if (mDownloadManager == null) {
            mDownloadManager = new DownloadManager(mContext.getContentResolver(), getPackageName());
        }
        return mDownloadManager;
    }

    public static Session getInstance() {

        return BaseApp.getInstance().getSession();
    }

    public int getOsVersionInt() {
        return osVersionCode;
    }

    public String getOsVersion() {
        return osVersion;
    }


    /**
     * 获取手机厂商
     *
     * @return 手机厂商
     */
    public String getDeviceBrand() {
        return brand;
    }

    public String getBuildVersion() {
        return buildVersion;
    }

    private void getApplicationInfo() {
        int permissionCheck = ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE);
        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
            TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
            imei = telMgr.getDeviceId();
            imsi = telMgr.getSubscriberId();
            sim = telMgr.getSimSerialNumber();
            phoneNumber = telMgr.getLine1Number();
        }
    }

    public String getVersionName() {
        return versionName;
    }

    public int getVersionCode() {
        return versionCode;
    }

    public String getIMEI() {
        if (TextUtils.isEmpty(imei)) {
            getApplicationInfo();
        }
        return imei;
    }

    public String getPackageName() {
        return packageName;
    }

    public String getSim() {
        if (TextUtils.isEmpty(sim)) {
            getApplicationInfo();
        }
        return sim;
    }

    public String getIMSI() {
        if (TextUtils.isEmpty(imsi)) {
            getApplicationInfo();
        }
        return imsi;
    }

    /**
     * Android6.0之后，权限收紧，地址为02:00:00:00:00:00
     *
     * @return mac地址
     */
    public String getMac() {
        if (TextUtils.isEmpty(macAddress)) {
            getWifiInfo();
        }
        return macAddress;
    }

    private void getWifiInfo() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            macAddress= getMacAddressOfM();
        } else {
            WifiManager wifi = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
            WifiInfo info = wifi.getConnectionInfo();
            macAddress = info.getMacAddress();
        }


    }

    public static String getMacAddressOfM() {
        try {
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
                byte[] macBytes = nif.getHardwareAddress();
                if (macBytes == null) {
                    return "";
                }
                StringBuilder res1 = new StringBuilder();
                for (byte b : macBytes) {
                    res1.append(String.format("%02X:",b));
                }
                if (res1.length() > 0) {
                    res1.deleteCharAt(res1.length() - 1);
                }
                return res1.toString();
            }
        } catch (Exception ex) {
        }
        return "02:00:00:00:00:00";
    }


    public boolean isLogin() {
        return isLogin;
    }

    public String getAppName() {
        return appName;
    }

    public String getModel() {
        return model;
    }

    public String getAndroidId() {
        return androidId;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public String getDeviceId() {
        if (TextUtils.isEmpty(deviceId)) {
            int permissionCheck = ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE);
            if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                deviceId = Utils.md5(getIMEI(), getAndroidId());
            }
        }
        return deviceId;
    }

}